home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / util / libs / graphics3d.lha / src / library / graphics3D2d.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-17  |  14.8 KB  |  636 lines

  1. /*
  2. **      $VER: graphics3D2d.c 11.00 (10.05.98)
  3. **
  4. **      External functions for graphics3D.library
  5. **    
  6. **      (C) Copyright 97 Patrizio Biancalani
  7. **      All Rights Reserved.
  8. */
  9.  
  10. #include <exec/types.h>
  11. #include <exec/memory.h>
  12. #include <proto/exec.h>
  13. #include <proto/intuition.h>
  14. #include <intuition/intuition.h>
  15. #include <intuition/screens.h>
  16.  
  17. #include <graphics/rastport.h>
  18. #include <graphics/clip.h>
  19. #include <graphics/regions.h>
  20. #include <graphics/gfx.h>
  21. #include <graphics/gfxmacros.h>
  22. #include <graphics/layers.h>
  23.  
  24. #include "graphics3Dc.h"
  25. #include "graphics3D.h"
  26. #include "graphics3D2d_proto.h"
  27.  
  28.  /* Please note, that &Graphics3DBase always resides in register __a6 
  29.     as well, but if we don't need it, we need not reference it here.
  30.  
  31.     Also note, that registers a0, a1, d0, d1 always are scratch registers,
  32.     so you usually should only *pass* parameters there, but make a copy
  33.     directly after entering the function. To avoid problems of kind
  34.     "implementation defined behaviour", you should make a copy of A6 too,
  35.     when it is actually used.
  36.  
  37.     In this example case, scratch register saving would not have been 
  38.     necessary (since there are no other function calls inbetween), but we 
  39.     did it nevertheless.
  40.   */
  41.  
  42. struct pixl {
  43.     long int x;
  44.     long int y;
  45.     };
  46.  
  47. /************ prototipi solo locali ******/
  48. struct RastPort *InitNBuff(struct grafica *graf);
  49.  
  50. void FreeNBuff(struct grafica *graf);
  51.  
  52. /**********************************************************/
  53.  
  54. /************ macro solo locali ******/
  55. #define DIPIU 500 
  56. #define PREC 8
  57. /*************************************/
  58.  
  59. /****************************************************
  60.  ** Routin per la gestione della grafica, in stile **
  61.  ** 2.0                                            ** 
  62.  ** (c) 1994 BIANCA HARD&SOFT Vers:1.00            **
  63.  ****************************************************/
  64.  
  65. /********* FUNZIONI 2D ********************************/
  66.  
  67. /***********************************
  68.  ** INIZIALIZZO STRUTTURE PER USO **
  69.  ** CON ROUTIN DI AREA FILL       **
  70.  ***********************************
  71.  **** INPUT :              **
  72.  ** win -> puntatore a finestra   **
  73.  **        su cui lavorare.       **
  74.  ** mxv -> n# massimo vertici da  **
  75.  **        usare.          **
  76.  **** OUTPUT :                    **
  77.  ** ris >0  - tutto ok.           **
  78.  ** ris =<0 - errore, ini.fallita.**
  79.  ***********************************/
  80. struct grafica *ini_g(struct Window *win,long int mxv,long int dx,long int dy)
  81. {
  82. struct grafica *ris;
  83. struct Screen *scr;
  84. struct RastPort *rw;
  85. struct RastPort *r;
  86. struct Layer *la;
  87. long int i;
  88.  
  89. ris=(struct grafica *)AllocMem(sizeof(Sgrafica),NULL);
  90. if (ris==NULL) return (0);
  91.  
  92. ris->vpor=0;
  93. ris->rast=0;
  94. ris->rast1=0;
  95. ris->rast2=0;
  96. ris->fdouble=1;
  97. ris->b_af=0;
  98. ris->pras=0;
  99.  
  100. /** default si single buffer **/
  101. ris->clipx=0;
  102. ris->clipy=0;
  103. i=((dx+15)/16)*16;
  104. ris->clipdx=i;
  105. ris->clipdy=dy;
  106. ris->dbuf=0;
  107. ris->ldbuf=0;
  108. ris->tmp_rp.BitMap=0;
  109. ris->NB_rinfo=0;       
  110. ris->NB_bmap=0;        
  111. ris->NB_layerinfo=0;   
  112. ris->NB_layer=0;       
  113.  
  114. rw=win->RPort;
  115. scr=win->WScreen;
  116. ris->vpor=&(scr->ViewPort);
  117. la=win->WLayer;
  118. ris->wind=win;
  119. ris->larg=LTMP;
  120. ris->alte=ATMP;
  121.  
  122. r=InitNBuff(ris);
  123. if ((long int)r==NULL) {
  124.     close_g(ris);
  125.     return(0);
  126.     }
  127. ris->rast1=rw;
  128. ris->rast2=r;
  129. ris->rast=r;
  130. ris->o_ai=r->AreaInfo;
  131. ris->o_tr=r->TmpRas;
  132.  
  133. /* se per buffer richiesto meno di 1 vertice e' meglio evitare */
  134. if (mxv<=1) {
  135.     close_g(ris);
  136.     return(0);
  137.     }
  138. /* faccio in modo di allineare alle words la dimensione dell'area */
  139. i=mxv;
  140. if (((mxv>>1)<<1)!=mxv) i++;
  141. ris->b_af=AllocMem(MAXVER(i),NULL);
  142. if (ris->b_af==NULL) {
  143.     close_g(ris);
  144.     return(0);    
  145.     }
  146. ris->lb_af=i;
  147.  
  148. InitArea(&ris->n_ai,ris->b_af,mxv);
  149. r->AreaInfo=&ris->n_ai;
  150.  
  151. ris->pras=(char *)AllocRaster(ris->larg,ris->alte);
  152. if (ris->pras==NULL) {
  153.     close_g(ris);
  154.     return (0);
  155.     }
  156.  
  157. InitTmpRas(&ris->n_tr,ris->pras,RASSIZE(ris->larg,ris->alte));
  158.  
  159. r->TmpRas=&ris->n_tr;
  160.  
  161. return(ris);
  162. }
  163.  
  164. /***********************************
  165.  ** CHIUDO TUTTE LE STRUTTURE     **
  166.  ** APERTE CON LA FUNZIONE PRECE- **
  167.  ** DENTE.                        **
  168.  ***********************************
  169.  **** INPUT :                     **
  170.  ** graf -> valore >0 ritornato   **
  171.  **         dalla funzione d'ini- **
  172.  **         zializzazione         **
  173.  ***********************************/
  174. void close_g(struct grafica *graf)
  175. {
  176. struct RastPort *r;
  177. struct Layer *la;
  178. long int c;
  179.  
  180. if ((long int)graf != NULL)
  181.     {
  182.     la=graf->wind->WLayer;
  183.     if (graf->fdouble!=NULL) la=graf->NB_layer;
  184.     if (la->ClipRegion!=NULL)
  185.         {
  186.         c=InstallClipRegion(la,NULL);
  187.         DisposeRegion(c);
  188.         }
  189.     r=graf->rast;
  190.     if ((long int)r > NULL )
  191.         {
  192.         r->AreaInfo=graf->o_ai;
  193.         r->TmpRas=graf->o_tr;
  194.         }
  195.     if (graf->b_af!=NULL) FreeMem(graf->b_af,MAXVER(graf->lb_af));
  196.     if (graf->pras!=NULL) FreeRaster(graf->pras,graf->larg,graf->alte);
  197.     if (graf->fdouble!=NULL) FreeNBuff(graf);
  198.     FreeMem(graf,sizeof(Sgrafica));
  199.     }
  200. }
  201.  
  202. /************************************
  203.  ** FUNZIONE PER VISUALIZZARE LA   **
  204.  ** RASTPORT NASCOSTA SULLA        **
  205.  ** FINESTRA.               **
  206.  ************************************
  207.  **** INPUT :               **
  208.  ** graf -> valore >0 ritornato    **
  209.  **         dalla funzione d'ini-  **
  210.  **         zializzazione.         **
  211.  **** OUTPUT:               **
  212.  ************************************/
  213. void switch_rp(graf)
  214. struct grafica *graf;
  215. {
  216.  
  217. /** se libreria non ottimizzata **/
  218. ClipBlit(graf->rast2,graf->clipx,graf->clipy,graf->rast1,graf->clipx,
  219.     graf->clipy,graf->clipdx,graf->clipdy,0xc0);
  220. WaitBlit();
  221.  
  222. }
  223.  
  224. /************************************
  225.  ** FUNZIONE PER DEFINIRE UN BOX   **
  226.  ** DI CLIP SULLA FINESTRA         **
  227.  ************************************
  228.  **** INPUT :               **
  229.  ** graf -> valore >0 ritornato    **
  230.  **         dalla funzione d'ini-  **
  231.  **         zializzazione.         **
  232.  ** minx - valore minimo x box.    **
  233.  ** miny - valore minimo y box.    **
  234.  ** dx - larghezza box.           **
  235.  ** dy - altezza box.           **
  236.  **** OUTPUT:               **
  237.  ** > 0 tutto ok, valore effettivo **
  238.  **     larghezza box in pixel.    ** 
  239.  ** = 0 errore.               **
  240.  **** NOTA:               **
  241.  ** elimina eventuali clip region  **
  242.  ** preesistenti.              **
  243.  ** Se dx o dy =0 allora ritorna   **
  244.  ** valore effettivo di dx.        **
  245.  ************************************/
  246. long int clipbox(struct grafica *graf,long int minx,
  247.            long int miny,long int dx,long int dy)
  248. {
  249. struct Layer *la;
  250. struct Region *clipr;
  251. struct Rectangle rect;
  252. struct ClipRect *clrt;
  253. long int esi;
  254. long int i;
  255.  
  256. #ifdef DEBUG
  257. char dbg[80];
  258. #endif
  259.  
  260. if (dx==0 OR dy==0) return(graf->clipdx);
  261.  
  262. i=((dx+15)/16)*16;
  263.  
  264. graf->clipx=minx;
  265. graf->clipy=miny;
  266.  
  267. #ifdef DEBUG
  268. sprintf(dbg,"mx=%ld my=%ld dx=%ld dy=%ld \n",minx,miny,dx,dy);
  269. write_dbg(dbg);
  270. #endif
  271.  
  272. graf->clipdx=i;
  273. graf->clipdy=dy;
  274.  
  275. la=graf->wind->WLayer;
  276. if (graf->fdouble) la=graf->NB_layer;
  277.  
  278. /*
  279. if (minx==0 AND miny==0 AND dx==0 AND dy==0)
  280.     {
  281.     if (graf->fdouble)
  282.         {
  283.         }
  284.     else
  285.         {
  286.         clipr=(struct Region *)InstallClipRegion(la,NULL);
  287.         if (clipr) DisposeRegion(clipr);
  288.         return (0);
  289.         }
  290.     }
  291. if (graf->fdouble==NULL)
  292.     {
  293.     wn=graf->wind;
  294.     la=wn->WLayer;
  295.     }
  296. */
  297.  
  298. /** elimino eventuali clipregion preesistenti **/
  299. clipr=(struct Region *)InstallClipRegion(la,NULL);
  300. if (clipr) DisposeRegion(clipr);
  301.  
  302. /** inizializzo una nuova clip region vuota **/
  303. clipr=(struct Region *)NewRegion();
  304. if (clipr==NULL) return (0);
  305.  
  306. rect.MinX=0;
  307. rect.MinY=0;
  308. if(graf->fdouble==NULL) 
  309.     {
  310.     rect.MinX=graf->clipx;
  311.     rect.MinY=graf->clipy;
  312.     }
  313. rect.MaxX=graf->clipdx;
  314. rect.MaxY=graf->clipdy;
  315.  
  316. OrRectRegion(clipr,&rect);
  317. InstallClipRegion(la,clipr);
  318.  
  319. return (graf->clipdx);
  320. }
  321.  
  322. /*************************************
  323.  ** FUNZIONE PER CANCELLARE UN BOX  **
  324.  ** NELLA FINESTRA .            **
  325.  *************************************
  326.  **** INPUT :                       **
  327.  ** graf -> valore >0 ritornato da  **
  328.  **         ini_g().                **
  329.  ** x0   -> coord. x punto in alto  **
  330.  **         a sinistra box.         **
  331.  ** y0   -> coord. y punto in alto  **
  332.  **         a sinistra box.         **
  333.  ** x1   -> coord. x punto in basso **
  334.  **         a destra box.        **
  335.  ** y1   -> coord. y punto in basso **
  336.  **        a destra box.        **
  337.  **** NOTA :                **
  338.  ** usa il colore dello sfondo, e   **
  339.  ** non influenza le altre funzioni **
  340.  *************************************/
  341. void cls_b(struct grafica *graf,long int x0,
  342.     long int y0,long int x1,long int y1)
  343. {
  344. long int i;
  345. char c,*db;
  346. if (((long int)graf<=NULL) OR ((long int)(graf->rast)<=NULL)) return(0); 
  347.  
  348. /* se uso libreria non ottimizzata */
  349. EraseRect(graf->rast,x0,y0,x1,y1);
  350. }
  351.  
  352. /*************************************
  353.  ** FUNZIONE PER CAMBIARE IL MODO   **
  354.  ** VIDEO DI TRACCIAMENTO.          **
  355.  *************************************
  356.  **** INPUT :                       **
  357.  ** graf -> valore >0 ritornato da  **
  358.  **         ini_g().                **
  359.  ** mod  -> nuovo modo video.       **
  360.  **** NOTA :                **
  361.  ** valori per mod :            **
  362.  ** 0 > JAM1 (over 2)            **
  363.  ** 1 > JAM2 (over 0) (def.)        **
  364.  ** 2 > COMPLEMENT (over 1)         **
  365.  ** 4 > INVERSVID  (inverse 1)      **
  366.  *************************************/
  367. void over(struct grafica *graf,long int mod)
  368. {
  369. if (((long int)graf<=NULL) OR ((long int)(graf->rast)<=NULL)) return(0); 
  370.  
  371. SetDrMd(graf->rast,mod);
  372. }
  373.  
  374. /********* ROUTIN INTERNE PER PSEUDO DOUBLE BUFFERING ***************/
  375. /*********************************************
  376.  ** INIZIALIZZO NUOVA RASTPORT PER USARLA   **
  377.  ** COME AREA DI RENDERING NASCOSTA.        **
  378.  *********************************************
  379.  **** INPUT :                    **
  380.  **** OUTPUT:                    **
  381.  ** se > 0 allora puntatore a nuova rastport**
  382.  *********************************************
  383.  ** nota: inizializzo una bitmap uguale     **
  384.  ** alla finestra usata per visualizzare la **
  385.  ** scena effettivamente.                **
  386.  *********************************************/
  387. struct RastPort *InitNBuff(struct grafica *graf)
  388. {
  389. struct RastPort *rport = NULL;  
  390. struct Window *win;
  391. struct Screen *screen;
  392. short int err = NULL;
  393. unsigned char depth;
  394. long int i;
  395. #ifdef DEBUG
  396. char dbg[100];
  397. #endif
  398.  
  399. win=graf->wind;
  400. screen=win->WScreen;
  401. depth=screen->BitMap.Depth;
  402.  
  403. graf->tmp_rp.BitMap=NULL;
  404. graf->dbuf=NULL;
  405.  
  406. /** 
  407.    Uso routin non ottimizzate passo da una rastport con display buffer nascosto
  408.    di tipo planar per usare il blitter
  409. **/
  410. if (!(graf->NB_layerinfo = (struct Layer_Info *)NewLayerInfo())) 
  411.     return (NULL);
  412.  
  413. if (!(graf->NB_bmap =(struct BitMap *)AllocBitMap(win->Width+SMARG,
  414.     win->Height+SMARG,depth,BMF_CLEAR|BMF_DISPLAYABLE,
  415.     graf->rast1->BitMap))) {
  416.    err = 3;
  417.    goto NBInit_done;
  418.    }
  419.  
  420. if (!(graf->NB_layer = (struct Layer *)CreateBehindLayer(graf->NB_layerinfo,
  421.         graf->NB_bmap,SMARGM,SMARGM, win->Width-1, win->Height-1,
  422.         LAYERSIMPLE|LAYERBACKDROP, NULL))) {
  423.    err = 4;
  424.    goto NBInit_done;
  425.    }
  426. rport = graf->NB_layer->rp;
  427.  
  428. SetRast(rport, 0);   
  429.  
  430. NBInit_done:
  431. if (err) FreeNBuff(graf);
  432. return (rport);
  433. }
  434.  
  435. /***************************************************
  436.  ** CHIUDO TUTTE LE AREE APERTE DALLA InitNBuff() **
  437.  ***************************************************/
  438. void FreeNBuff(struct grafica *graf)
  439. {
  440. unsigned char depth;
  441. struct RastPort *rp;
  442.  
  443. rp=graf->rast2;
  444. if (graf->NB_layer) DeleteLayer(0L, graf->NB_layer);
  445. if (graf->NB_layerinfo) DisposeLayerInfo(graf->NB_layerinfo);
  446.  
  447. if (graf->NB_bmap) 
  448.     {
  449.     WaitBlit();
  450.     FreeBitMap(graf->NB_bmap);  
  451.     }
  452. }
  453.  
  454. /********* FUNZIONI 2D NON OTTIMIZZATE ********************************/
  455.  
  456. /***********************************
  457.  ** RIEMPIO IL DISPLAY FILE COL   **
  458.  ** COLORE DELLO SFONDO.      **
  459.  ***********************************
  460.  **** INPUT :              **
  461.  ** amb3d -> valore >0 ritornato  **
  462.  **         dalla funzione d'ini- **
  463.  **         zializzazione.        **
  464.  **** OUTPUT:              **
  465.  ** nessuno .              **
  466.  ***********************************/
  467. void cls_f(amb3d)
  468. struct ambient3d *amb3d;
  469. {
  470.  
  471. SetRast(amb3d->graf->rast,amb3d->gcolor);
  472.  
  473. }
  474.  
  475. /***********************************
  476.  ** DISEGNO UN PIXEL NEL DISPLAY  **
  477.  ** BUFFER CHUNKY.          **
  478.  ***********************************
  479.  **** INPUT :              **
  480.  ** amb3d -> valore >0 ritornato  **
  481.  **         dalla funzione d'ini- **
  482.  **         zializzazione.        **
  483.  ** x  -> coordinata x .      **
  484.  ** y  -> coordinata y .      **
  485.  **** OUTPUT:              **
  486.  ** nessuno .              **
  487.  ***********************************/
  488. void pixel(amb3d,x,y,col)
  489. struct ambient3d *amb3d;
  490. short int x;
  491. short int y;
  492. long int col;
  493. {
  494. char cl;
  495. struct RastPort *rast;
  496.  
  497. rast=amb3d->graf->rast;
  498. cl=rast->FgPen;
  499.  
  500. SetAPen(rast,col);
  501. WritePixel(rast,x,y);
  502. SetAPen(rast,cl);
  503.  
  504. }
  505.  
  506. /***********************************
  507.  ** DISEGNO UNA RIGA NEL DISPLAY  **
  508.  ** BUFFER CHUNKY.          **
  509.  ***********************************
  510.  **** INPUT :              **
  511.  ** amb3d -> valore >0 ritornato  **
  512.  **         dalla funzione d'ini- **
  513.  **         zializzazione.        **
  514.  ** x  -> coordinata x partenza.  **
  515.  ** y  -> coordinata y partenza.  **
  516.  ** x1 -> coordinata x arrivo.      **
  517.  ** y1 -> coordinata y arrivo.      **
  518.  **** OUTPUT:              **
  519.  ** nessuno .              **
  520.  ***********************************/
  521. void line(amb3d,x,y,x1,y1,col)
  522. struct ambient3d *amb3d;
  523. short int x;
  524. short int y;
  525. short int x1;
  526. short int y1;
  527. long int col;
  528. {
  529. char cl;
  530. struct RastPort *rast;
  531.  
  532. rast=amb3d->graf->rast;
  533. cl=rast->FgPen;
  534.  
  535. SetAPen(rast,col);
  536.  
  537. Move(rast,x,y);
  538. Draw(rast,x1,y1);
  539.  
  540. SetAPen(rast,cl);
  541.  
  542.  
  543. }
  544. /***********************************
  545.  ** DISEGNO UN TRIANGOLO CON O    **
  546.  ** SENZA BORDO NEL DISPLAY       **
  547.  ** BUFFER CHUNKY.          **
  548.  ***********************************
  549.  **** INPUT :              **
  550.  ** amb3d -> valore >0 ritornato  **
  551.  **         dalla funzione d'ini- **
  552.  **         zializzazione.        **
  553.  ** buf  -> puntatore ad array di **
  554.  **        short int con coordi- **
  555.  **         nate vertici.      **
  556.  ** col  -> short int con colore  **
  557.  **        triangolo.          **
  558.  ** bordo-> =-1 senza bordo       **
  559.  **         >=0 colore bordo.     **
  560.  **** OUTPUT:              **
  561.  ** nessuno .              **
  562.  ***********************************/
  563. void drw_t(amb3d,buf,col,bordo)
  564. struct ambient3d *amb3d;
  565. short int *buf;
  566. long int col;
  567. long int bordo;
  568. {
  569. struct RastPort *rast;
  570. char cl;
  571.  
  572. rast=amb3d->graf->rast;
  573. cl=rast->FgPen;
  574.  
  575. SetAPen(rast,col);
  576.  
  577. BNDRYOFF(rast)
  578. if (bordo>=NULL) SetOutlinePen(rast,bordo);
  579.  
  580. AreaMove(rast,buf[0],buf[1]);
  581. AreaDraw(rast,buf[2],buf[3]);
  582. AreaDraw(rast,buf[4],buf[5]);
  583. AreaEnd(rast);
  584.  
  585. SetAPen(rast,cl);
  586.  
  587. }
  588.  
  589. /***********************************
  590.  ** DISEGNO UN QUADRILATERO CON O **
  591.  ** SENZA BORDO NELLA RASTPORT    **
  592.  ** NASCOSTA.              **
  593.  ***********************************
  594.  **** INPUT :              **
  595.  ** amb3d-> valore >0 ritornato   **
  596.  **         dalla funzione d'ini- **
  597.  **         zializzazione.        **
  598.  ** buf  -> puntatore ad array di **
  599.  **        short int con coordi- **
  600.  **         nate vertici.      **
  601.  ** col  -> short int con colore  **
  602.  **        triangolo.          **
  603.  ** bordo-> =-1 senza bordo       **
  604.  **         >=0 colore bordo.     **
  605.  **** OUTPUT:              **
  606.  ** nessuno .              **
  607.  ***********************************/
  608. void drw_q(amb3d,buf,col,bordo)
  609. struct ambient3d *amb3d;
  610. short int *buf;
  611. long int col;
  612. long int bordo;
  613. {
  614. struct RastPort *rast;
  615. char cl;
  616.  
  617. rast=amb3d->graf->rast;
  618. cl=rast->FgPen;
  619.  
  620. SetAPen(rast,col);
  621.  
  622. BNDRYOFF(rast)
  623. if (bordo>=NULL) SetOutlinePen(rast,bordo);
  624.  
  625. AreaMove(rast,buf[0],buf[1]);
  626. AreaDraw(rast,buf[2],buf[3]);
  627. AreaDraw(rast,buf[4],buf[5]);
  628. AreaDraw(rast,buf[6],buf[7]);
  629. AreaEnd(rast);
  630.  
  631. SetAPen(rast,cl);
  632.  
  633.  
  634. }
  635.  
  636.